# coding:utf-8
'''
Created on 2015年6月25日

@author: Emrys
'''
import types
from functools import wraps


class A:

    def decorator1(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print('Decorator 1')
            return func(*args, **kwargs)
        return wrapper

    @classmethod
    def decorator2(cls, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print('Decorator 2')
            return func(*args, **kwargs)
        return wrapper


# 这是property的一种用法
class Person:
    first_name = property()

    @first_name.getter
    def first_name(self):
        print("first_name.getter")
        return self._first_name

    @first_name.setter
    def first_name(self, value):
        print("first_name.setter")
        if not isinstance(value, str):
            raise TypeError('Expected a string')
        self._first_name = value


class Profiled:

    def __init__(self, func):
        wraps(func)(self)
        self.ncalls = 0

    def __call__(self, *args, **kwargs):
        self.ncalls += 1
        return self.__wrapped__(*args, **kwargs)

    def __get__(self, instance, cls):
        print("Progfiled __get__")
        if instance is None:
            return self
        else:
            return types.MethodType(self, instance)


class Spam:

    @Profiled
    def bar(self, x):
        print(self, x)


class T:

    def t(self, a):
        print("t")

    def __get__(self, instance, cls):
        print("T __get__")
        return self


@Profiled
def add(x, y):
    return x + y

if __name__ == "__main__":
    # person = Person()
    #     person.first_name = "123"
    #     person.first_name
    #     add(1, 2)
    #     print(add.ncalls)
    #     s = Spam()
    #     s.bar(3)
    t = T()
    t.t(3)
